from Common.BaseView import BaseView, Blueprint, Api, request, session
from flask_login import login_user, logout_user, current_user
from Modules.sys_account.model import db, AccountModel
from Plugins.helper import generate_raskey, generate_deskey, rsa_decrypt
from Modules.sys_log.view import system_log
import json
from flask import make_response, jsonify

login_bp = Blueprint('login', __name__, url_prefix='/api')
api = Api(login_bp)


# 递归实现用户菜单
def create_menu(menu=None, module=None, action=None, actions=[]):
    menus = []

    while len(actions) > 0:
        actions_ins = actions.pop()
        module_obj = create_menu(menu=menus, module=actions_ins.module, action=actions_ins)
        # action['mark...']
        if 'actions' in module_obj:
            for action_item in module_obj['actions']:
                if actions_ins.mark == action_item:
                    break
            else:
                module_obj['actions'].append(actions_ins.mark)
        else:
            module_obj['actions'] = [actions_ins.mark]

    if module is None:
        menus = sorted(menus, key=lambda x: x['id'])
        return menus

    if module.pid is not None:
        module_ins = create_menu(menu=menu, module=module.parent)
        module_dict = {'id': module.id, 'name': module.name, 'icon': module.icon, 'url': module.url}
        if 'children' in module_ins:
            for child in module_ins['children']:
                if child['id'] == module.id:
                    return child
            else:
                module_ins['children'].append(module_dict)
                module_ins['children'] = sorted(module_ins['children'], key=lambda x: x['id'])
                return module_dict
        else:
            module_ins['children'] = [module_dict]
            return module_dict
    else:
        for m_item in menu:
            if m_item['id'] == module.id:
                return m_item
        else:
            menu.append({'id': module.id, 'name': module.name, 'icon': module.icon})
            return menu[-1]


class LoginView(BaseView):
    method_decorators = [system_log]

    def get(self):
        try:
            scope = request.args.get('scope')
            if scope == 'getkey':
                generate_raskey()
                generate_deskey()
                pubkey = session.get('pubkey')
                response = make_response(self.result('0x00010', data=pubkey.decode()))
                response.set_cookie('secret-key', session.get('secret'))
                return response
                # return self.result('0x00010', data=pubkey.decode())
            if scope == 'login':
                account_info = json.loads(rsa_decrypt(request.args.get('enc_data')))
                if account_info is None:
                    return self.result('0x00004')
                account = AccountModel.query.filter_by(username=account_info['uname']).first()
                if account is None:
                    return self.result('0x00001')
                if account.status is False:
                    return self.result('0x00006')
                if account.check_password(account_info['upass']) is False:
                    return self.result('0x00002')
                login_user(account)
                return self.result('0x00005')
            if scope == 'status':
                if current_user.is_authenticated:
                    # return self.result('0x00009')
                    return jsonify({'code': '0x00009', 'msg': '已经登录'})
                else:
                    # return self.result('0x00008')
                    return jsonify({'code': '0x00008', 'msg': '请先登录'})
            if scope == 'menu':
                if not current_user.is_authenticated:
                    return self.result('0x00011')
                roles = current_user.roles
                actions = []
                for role in roles:
                    actions.extend(role.actions)
                menus = create_menu(actions=actions)
                return self.result('0x00010', data=menus)
            if scope == 'userinfo':
                if not current_user.is_authenticated:
                    return self.result('0x00011')
                result_data = {'department': '', 'fullname': current_user.username}
                # 帐号对应职员所属部门

                return self.result('0x00010', data=result_data)
        except Exception as error:
            return self.result('0x00011', data='%s' % error)

    def put(self):
        try:
            data_dict = json.loads(rsa_decrypt(request.json['enc_data']))
            if current_user.check_password(data_dict['oldpwd']) is False:
                return self.result('0x00017', data='原密码错误')
            if data_dict['newpwd'] != data_dict['verpwd']:
                return self.result('0x00017', data='新密码不一致')
            current_user.password = data_dict['newpwd']
            db.session.commit()
            return self.result('0x00016')
        except Exception as error:
            return self.result('0x00017', data='%s' % error)

    def delete(self):
        try:
            if current_user.is_authenticated:
                logout_user()
                return self.result('0x00007')
            else:
                return self.result('0x00004')
        except Exception as error:
            return self.result('0x00004', data='%s' % error)


api.add_resource(LoginView, '/login')
